home *** CD-ROM | disk | FTP | other *** search
/ Programmers Heaven 2 / Programmers Heaven 2.iso / files / graphics / library / wgt51_r2.zip / WGT5 / 3D / 3D_CAM.C next >
Encoding:
C/C++ Source or Header  |  1996-08-03  |  17.8 KB  |  781 lines

  1. #include <dos.h>
  2. #include <math.h>
  3. #include <malloc.h>
  4. #include <wgt5.h>
  5. #include <wgtvesa.h>
  6. #include "wrend.h"
  7.  
  8. #define PHONG 8
  9. #define PHONG_TEXTURE 9
  10. #define TRANSLUCENT_PHONG 10
  11.  
  12. int rendermethod;
  13. int motion_blur;
  14. float percent_foreground;
  15. float percent_background;
  16. float motion_blur_factor;
  17. block virt;                        /* Drawing buffer */
  18. color pal[256];                    /* A palette */
  19.  
  20. /* For shaded texture mapping */
  21. #define NUMSHADES 64               /* Number of shades in the shade table */
  22. block shadetable;                  /* allocated dynamically, has a size
  23.                       of (NUMSHADES+1) * 256 bytes */
  24.  
  25. block translucent_table;           /* allocated dynamically, has a size
  26.                       of 256 * 256 bytes */
  27.  
  28. float scale = 1;                /* Scale used for mapping a texture onto
  29.                       a plane */
  30.  
  31. float movectr = 5;                 /* Movement speed for camera, rotation... */
  32.  
  33. #define POINTBUF 10000
  34. vertex vertices[POINTBUF];         /* Vertex list for world */
  35.  
  36. short vmodes[6] = { V640x350, V640x400, V640x480, V800x600, V1024x768 };
  37.  
  38.  
  39. void set_initial_palette (void)
  40. {
  41. int i, c, r, g, b;
  42. double u;
  43.  
  44. // Phong material properties
  45. #define SHINE   80.0
  46. #define SPEC    0.70
  47. #define PI      3.141516
  48. #define R0      63
  49. #define G0      18
  50. #define B0      15
  51.  
  52.  
  53. /* Phong Palette */
  54. if ((rendermethod == PHONG) || (rendermethod == TRANSLUCENT_PHONG))
  55.  {   
  56.    for (i = 0; i < 256; i++) 
  57.      {
  58.       u = SPEC*63.0*exp(SHINE*log(sin(0.5*PI*i/256.0)+0.001));
  59.       if ((r = (i*R0/256) + u) > 63) r = 63;
  60.       if ((g = (i*G0/256) + u) > 63) g = 63;
  61.       if ((b = (i*B0/256) + u) > 63) b = 63;
  62.       
  63.       wsetrgb (i, r, g, b, pal);
  64.      }
  65.  
  66.   }
  67. else
  68.   {
  69.    /* Set up some initial color ranges */
  70.    for (i = 0; i < 64; i++)
  71.     {
  72.      pal[i].r = i;
  73.      pal[i].g = i;
  74.      pal[i].b = 0;
  75.     }
  76.    for (i = 64; i < 128; i++)
  77.     {
  78.      pal[i].r = i - 64;
  79.      pal[i].g = 0;
  80.      pal[i].b = 0;
  81.     }
  82.   
  83.    for (i = 128; i < 192; i++)
  84.     {
  85.      pal[i].r = i - 128;
  86.      pal[i].g = 0;
  87.      pal[i].b = i - 128;
  88.     }
  89.    for (i = 192; i < 256; i++)
  90.     {
  91.      pal[i].r = 0;
  92.      pal[i].g = 0;
  93.      pal[i].b = i - 192;
  94.     }
  95.   }
  96.   
  97.   wsetrgb (0, 0, 0, 0, pal);
  98.   wsetpalette (0, 255, pal);
  99. }
  100.  
  101.  
  102. void save_table (char *filename, block table, long size)
  103. {
  104. FILE *out;
  105. int i;
  106.  
  107.  out = fopen (filename, "wb");
  108.  fwrite (table, size, 1, out);
  109.  fclose (out);
  110. }
  111.  
  112.  
  113. block load_table (char *filename, long size)
  114. {
  115. FILE *in;
  116. int i;
  117. block table;
  118.  
  119.  in = fopen (filename, "rb");
  120.  if (in != NULL)
  121.   {
  122.    table = (unsigned char *)malloc (size);
  123.    fread (table, size, 1, in);
  124.    fclose (in);
  125.    return table;
  126.   }
  127.  else
  128.   return NULL;
  129. }
  130.  
  131.  
  132.  
  133.  
  134. void load_ptext (int num)
  135. {
  136. FILE *in;
  137. int i;
  138.  
  139. in = fopen ("face.txt", "rb");
  140.  
  141.  fread (ptext, sizeof(polytexture), num, in);   
  142.  fclose (in);
  143. }
  144.  
  145.  
  146. void save_ptext (int num)
  147. {
  148. FILE *out;
  149. int i;
  150.  
  151.  out = fopen ("face.txt", "wb");
  152.  fwrite (ptext, sizeof (polytexture), num, out);
  153.  fclose (out);
  154. }
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161. /* Shade Table Calculations */
  162. void wcreateshade (short shade, short maxshade, unsigned char *shadetable,
  163.            color *palette)
  164. /* Calculate a single palette (256) colors for the given shade */
  165. {
  166. float lightlevel;
  167. float fr, fg, fb;
  168. long ir, ig, ib;
  169.  
  170. long absr, absg, absb;
  171.  
  172.  
  173. double u;
  174. int r,g,b;
  175.  
  176. short col;
  177. short findcol;
  178.  
  179. unsigned long lowest;
  180. unsigned char bestfit;
  181. unsigned long coldif;
  182.  
  183.  
  184.  lightlevel = (float)shade / maxshade;
  185.  lightlevel += 0.2;
  186.  if (lightlevel > 1)
  187.      lightlevel = 1;
  188.  
  189.  for (col = 0; col < 256; col++)
  190.   {
  191.    fr = (float)palette[col].r * (lightlevel);
  192.    fg = (float)palette[col].g * (lightlevel);
  193.    fb = (float)palette[col].b * (lightlevel);
  194.  
  195.    /* Phong shade table */
  196.    if (rendermethod == PHONG_TEXTURE)
  197.      {   
  198.       u = SPEC*63.0*exp(SHINE*log(sin(0.5*PI*shade/maxshade)+0.001));
  199.       if ((fr = (fr + u)) > 63) fr = 63;
  200.       if ((fg = (fg + u)) > 63) fg = 63;
  201.       if ((fb = (fb + u)) > 63) fb = 63;
  202.      } 
  203.      
  204.    ir = fr;
  205.    ig = fg;
  206.    ib = fb;
  207.  
  208.    lowest = 655350;
  209.    for  (findcol = 0; findcol < 256; findcol++)
  210.     {
  211.       absr = abs ( (long)palette[findcol].r - ir);
  212.       absg = abs ( (long)palette[findcol].g - ig);
  213.       absb = abs ( (long)palette[findcol].b - ib);
  214.  
  215.       //coldif = absr*absr*30 + absg*absg*59 + absb*absb*11;
  216.       coldif = absr*absr + absg*absg + absb*absb;
  217.       coldif = sqrt (coldif);
  218.       if  (coldif < lowest)
  219.       {
  220.     lowest = coldif;
  221.     bestfit = findcol;
  222.       }
  223.     }
  224.    shadetable[shade*256 + col] = bestfit;
  225.   }
  226.  
  227. }
  228.  
  229.  
  230. block wcreate_shade_table (short numshades, color *palette)
  231. /* Create a shade table for shaded texture mapping, with darker colors
  232.    towards black. */
  233. {
  234. short i;
  235. block table;
  236.  
  237.  table = (unsigned char *)malloc ( (NUMSHADES+1)*256L);
  238.    
  239.  wtextcolor (128);
  240.  wtexttransparent (TEXTFGBG);
  241.  wgtprintf (0, 0, NULL, "Making shade table...");
  242.  
  243.  wnormscreen ();
  244.  for (i = 0; i <= numshades; i++)
  245.   { 
  246.    wgtprintf (0, 8, NULL, "Color %03hi", i);
  247.    wcreateshade (i, numshades, table, palette);
  248.   }
  249.  
  250.  return table;
  251. }
  252.  
  253.  
  254.  
  255.  
  256. block wcreate_translucent_table (color *pal)
  257. /* Creates a translucent table */
  258. {
  259. float lightlevel1;
  260. float lightlevel2;
  261. float fr, fg, fb;
  262. float fr2, fg2, fb2;
  263. long ir, ig, ib;
  264.  
  265. long absr, absg, absb;
  266.  
  267. short col, col2;
  268. short findcol;
  269.  
  270. unsigned long lowest;
  271. unsigned char bestfit;
  272. unsigned long coldif;
  273. unsigned char *table;
  274.  
  275.  table = (unsigned char *)malloc (65536);
  276.  
  277.  lightlevel1 = percent_foreground;   /* Percent of color 1 (foreground) */
  278.  lightlevel2 = percent_background;   /* Percent of color 2 (background) */
  279.  
  280.  /* Lightlevel1 and lightlevel2 must total to 1 */
  281.  
  282.  /* Translucency is created by taking two colors, multiplying the
  283.  RGB values by a percentage, and adding the RGB values together.  The
  284.  new color will contain a little bit of each oringal color. */
  285.  
  286.  
  287.  /* For each of the 256 colors, we can mix with any other color, therefore
  288.  we need a 256x256 table. */
  289.  
  290.  wtextcolor (128);
  291.  wtexttransparent (TEXTFGBG);
  292.  wgtprintf (0, 0, NULL, "Making translucency table... ");
  293.  
  294.  for (col2 = 0; col2 < 256; col2++)
  295.  {
  296.   for (col = 0; col < 256; col++)
  297.   {
  298.    fr = (float)pal[col].r * lightlevel1;
  299.    fg = (float)pal[col].g * lightlevel1;
  300.    fb = (float)pal[col].b * lightlevel1;
  301.  
  302.    fr2= (float)pal[col2].r * lightlevel2;
  303.    fg2= (float)pal[col2].g * lightlevel2;
  304.    fb2= (float)pal[col2].b * lightlevel2;
  305.  
  306.    ir = (fr + fr2);
  307.    ig = (fg + fg2);
  308.    ib = (fb + fb2);
  309.  
  310.    lowest = 655350;
  311.    for  (findcol = 0; findcol < 256; findcol++)
  312.     {
  313.       absr = abs ( (long)pal[findcol].r - ir) * 30;
  314.       absg = abs ( (long)pal[findcol].g - ig) * 59;
  315.       absb = abs ( (long)pal[findcol].b - ib) * 11;
  316.  
  317.  //     coldif = sqrt(absr*absr + absg*absg + absb*absb);
  318.      coldif = absr*absr + absg*absg + absb*absb;      
  319.       if  (coldif < lowest)
  320.       {
  321.     lowest = coldif;
  322.     bestfit = findcol;
  323.       }
  324.     }
  325.    table[col2 * 256L + col] = bestfit;
  326.   }
  327.  
  328.   wgtprintf (0, 8, NULL, "Color %03hi", col2);
  329.  }
  330.  
  331.  return table;
  332. }
  333.  
  334.  
  335. long move_counter;
  336. long frame_counter;
  337.  
  338. void movement_timer (void)
  339. {
  340.  frame_counter++;
  341. }
  342.  
  343.  
  344. void wshadesource (block shadetable, block source, int length);
  345. #pragma aux wshadesource = \
  346.  "push ebp" \
  347.  "push ecx" \
  348.  "cld" \
  349.  "mov ebp, edx" \
  350.  "mov ebx, 0" \
  351.  "mov edi, esi" \
  352.  "shr ecx, 1" \
  353.  "cmp ecx, 0" \
  354.  "je oneshadepixel"\
  355.  "shadeloop: mov bl, [esi]" \
  356.  "mov al, [ebp + ebx]" \
  357.  "inc esi" \
  358.  "mov bl, [esi]" \
  359.  "mov ah, [ebp + ebx]" \
  360.  "mov [edi], ax" \
  361.  "add edi, 2" \
  362.  "inc esi" \
  363.  "dec ecx" \
  364.  "jnz shadeloop" \
  365.  "oneshadepixel: pop ecx" \
  366.  "and ecx, 1" \
  367.  "jz slinedone" \
  368.  "mov bl, [esi]" \
  369.  "mov al, [ebp + ebx]" \
  370.  "mov [edi], al" \
  371.  "slinedone: pop ebp" \
  372. parm [edx] [esi] [ecx] \
  373. modify exact [eax ebx ecx edx esi edi] nomemory;
  374.  
  375.  
  376. unsigned char shadesourcetable[256];
  377.  
  378. void shade_screen (void)
  379. {
  380.  wshadesource (shadesourcetable, virt+4, 64000L);
  381. }
  382.  
  383.  
  384. void wcreate_shadesource_table (color *palette)
  385. {
  386. float fr, fg, fb;
  387. long ir, ig, ib;
  388.  
  389. long absr, absg, absb;
  390.  
  391.  
  392. int r,g,b;
  393.  
  394. short col;
  395. short findcol;
  396.  
  397. unsigned long lowest;
  398. unsigned char bestfit;
  399. unsigned long coldif;
  400.  
  401.  for (col = 0; col < 256; col++)
  402.   {
  403.  
  404.    fr = (float)palette[col].r * (motion_blur_factor);
  405.    fg = (float)palette[col].g * (motion_blur_factor);
  406.    fb = (float)palette[col].b * (motion_blur_factor);
  407.  
  408.    ir = fr;
  409.    ig = fg;
  410.    ib = fb;
  411.  
  412.    lowest = 655350;
  413.    for  (findcol = 0; findcol < 256; findcol++)
  414.     {
  415.       absr = abs ( (long)palette[findcol].r - ir);
  416.       absg = abs ( (long)palette[findcol].g - ig);
  417.       absb = abs ( (long)palette[findcol].b - ib);
  418.  
  419.       coldif = absr + absg + absb;
  420.       if  ((coldif < lowest) && (findcol != col))
  421.       {
  422.     lowest = coldif;
  423.     bestfit = findcol;
  424.       }
  425.     }
  426.    shadesourcetable[col] = bestfit;
  427.   }
  428.  
  429. }
  430.  
  431.  
  432.  
  433.  
  434.  
  435. void main(int argc, char *argv[])
  436. {
  437. short oldmode;
  438. int drawnum;
  439.  
  440. short i;
  441.  
  442. int vx, vy;
  443. int mx, my;
  444.  
  445. float rx, ry, rz;
  446. float trx, try, trz;
  447.  
  448.   oldmode = wgetmode();
  449.  
  450.   if (argc == 1)
  451.   {
  452.     printf ("\n3D_CAM filename.3ds [vmode]\n\nWhere vmode is one of:\n");
  453.     printf ("\n1 VESA  640x350x256");
  454.     printf ("\n2 VESA  640x400x256");
  455.     printf ("\n3 VESA  640x480x256");
  456.     printf ("\n4 VESA  800x600x256");
  457.     printf ("\n5 VESA 1024x768x256\n");
  458.     exit (0);
  459.   }
  460.  
  461.   printf ("Enter the rendering method: \n");
  462.   printf ("0 = Wireframe\n");
  463.   printf ("1 = Solid\n");
  464.   printf ("2 = Gouraud Shaded\n");
  465.   printf ("3 = Texture Mapped\n");
  466.   printf ("4 = Flat Shaded Texture Mapped\n");
  467.   printf ("5 = Gouraud Shaded Texture Mapped\n");
  468.   printf ("6 = Translucent Texture Mapped\n");
  469.   printf ("7 = Translucent Gouraud Shaded\n");
  470.   printf ("8 = Gouraud with Phong Palette\n");
  471.   printf ("9 = Gouraud Texture with Phong Palette\n");
  472.   printf ("10 = Translucent Gouraud with Phong Palette\n");
  473.   
  474.   scanf ("%d", &rendermethod);
  475.   if ((rendermethod < 0) || (rendermethod > 10))
  476.     exit (0);
  477.   
  478.   printf ("Motion Blur? 0 = NO, 1 = YES\n");
  479.   scanf ("%d", &motion_blur);
  480.   if ((motion_blur < 0) || (motion_blur > 1))
  481.     exit (0);
  482.   
  483.   if (motion_blur)
  484.    {
  485.     printf ("Fade Factor: (percentage of previous image)\n");
  486.     scanf ("%f", &motion_blur_factor);
  487.    }
  488.  
  489.   load_3ds (argv[1], vertices);
  490.   
  491.   for (i = 0; i < totalobjects; i++)
  492.    {
  493.     wset_object_color (i, 0);
  494.     
  495.     if (rendermethod == PHONG)
  496.       wset_object_type (i, GOURAUD);
  497.     else if (rendermethod == TRANSLUCENT_PHONG)
  498.       wset_object_type (i, TRANSLUCENT_GOURAUD);
  499.     else if (rendermethod == PHONG_TEXTURE)
  500.       wset_object_type (i, GOURAUD_SHADED_TEXTURE);
  501.     else 
  502.       wset_object_type (i, rendermethod);
  503.    }
  504.  
  505.   printf ("\n\n\n\n\n\nTotal of: %8d points\n", worldpoints);
  506.   printf ("Total of: %8d faces\n", totalpoly);
  507.   printf ("Total of: %8d objects\n", totalobjects);
  508.   printf ("Start obj 1 = %d\n", objectlist[0].start_poly);
  509.   printf ("End obj 1   = %d\n", objectlist[0].end_poly);
  510.  
  511.   printf ("Memory free: %8d\n\n\n", getmemfree() );
  512.   printf ("Keyboard Controls:\n");  
  513.   printf ("LEFT & RIGHT                 Dec/Inc X Camera position\n");
  514.   printf ("  UP & DOWN                  Dec/Inc Y Camera position\n");
  515.   printf ("PGUP & PGDN                  Dec/Inc Z Camera position\n");
  516.   printf ("PLUS & MINUS                 Inc/Dec Camera movement scale\n");
  517.   printf ("CTRL & one of the above      Rotate object\n");
  518.   printf ("   I & O                     Inc/Dec Texture Scale\n");
  519.   printf ("                        ESC           Quit\n");
  520.   getch ();
  521.   
  522.   if ((rendermethod == TRANSLUCENT_GOURAUD) ||
  523.       (rendermethod == TRANSLUCENT_PHONG) ||
  524.       (rendermethod == TRANSLUCENT_TEXTURE))
  525.      {
  526.       translucent_table = load_table ("trans.dat", 65536L);
  527.       if (translucent_table == NULL)
  528.     {
  529.      printf ("Translucent Factors\n");
  530.      printf ("Percentage of foreground:\n");
  531.      scanf ("%f", &percent_foreground);
  532.      printf ("Percentage of background:\n");
  533.      scanf ("%f", &percent_background);
  534.     }
  535.      }
  536.   
  537.  
  538.   vga256 ();
  539.   
  540.   if ((argc == 3) && (atoi (argv[2]) < 6) && (atoi (argv[2]) > 0))
  541.     wvesa_init (vmodes[atoi (argv[2]) - 1] );
  542.   /* Enter SVGA mode */
  543.   
  544.   render_all = 0;       /* Perform backface removal */
  545.   set_initial_palette ();  
  546.   wsetpalette (0, 255, pal);
  547.  
  548.  
  549.   if ((rendermethod == FLAT_SHADED_TEXTURE) ||
  550.       (rendermethod == TEXTURE) ||      
  551.       (rendermethod == GOURAUD_SHADED_TEXTURE) ||
  552.       (rendermethod == TRANSLUCENT_TEXTURE) ||
  553.       (rendermethod == PHONG_TEXTURE))
  554.   /* Using some kind of texture mapping */
  555.    {
  556.     textures[0] = wloadpcx ("texture.pcx", pal);
  557.     wsetpalette (0, 255, pal);
  558.     /* Load in the texture and set the palette */
  559.  
  560.  
  561.     /* Make any shade tables needed */
  562.     if ((rendermethod == FLAT_SHADED_TEXTURE) ||
  563.     (rendermethod == GOURAUD_SHADED_TEXTURE))
  564.       { 
  565.        shadetable = load_table ("shade.dat", (NUMSHADES + 1) * 256L);
  566.        if (shadetable == NULL)
  567.      {
  568.       shadetable = wcreate_shade_table (NUMSHADES, pal);
  569.       save_table ("shade.dat", shadetable, (NUMSHADES + 1) * 256L);
  570.      }
  571.        render_shadetable = shadetable;
  572.       }
  573.     else if (rendermethod == PHONG_TEXTURE)
  574.       { 
  575.        shadetable = load_table ("phong.dat", (NUMSHADES + 1) * 256L);
  576.        if (shadetable == NULL)
  577.      {
  578.       shadetable = wcreate_shade_table (NUMSHADES, pal);
  579.       save_table ("phong.dat", shadetable, (NUMSHADES + 1) * 256L);
  580.      }
  581.        render_shadetable = shadetable;
  582.       }
  583.     }
  584.  
  585.   if ((rendermethod == TRANSLUCENT_GOURAUD) ||
  586.       (rendermethod == TRANSLUCENT_PHONG) ||
  587.       (rendermethod == TRANSLUCENT_TEXTURE))
  588.      {
  589.       if (translucent_table == NULL)
  590.     {
  591.      translucent_table = wcreate_translucent_table (pal);
  592.      save_table ("trans.dat", translucent_table, 65536L);
  593.     }
  594.  
  595.       render_all = 1;
  596.       /* Render everything, since we will be able to see through the object */
  597.      
  598.       render_shadetable = translucent_table;
  599.       
  600.      }
  601.  
  602.   
  603.  
  604.   wclip (0, 0, WGT_SYS.xres - 1, WGT_SYS.yres - 1);
  605.   
  606.   winit_triangle_renderer (WGT_SYS.yres);
  607.  
  608.   virt = wnewblock (0, 0, WGT_SYS.xres - 1, WGT_SYS.yres - 1);
  609.   render_shades = 64;
  610.   
  611.   if (rendermethod == GOURAUD)
  612.    for (i = 0; i < totalobjects; i++)
  613.       wset_object_color (i, 0);
  614.    
  615.  
  616.   if ((rendermethod == PHONG) || (rendermethod == TRANSLUCENT_PHONG))
  617.    { 
  618.     for (i = 0; i < totalobjects; i++)
  619.       wset_object_color (i, 0);
  620.     render_shades = 256;
  621.    }
  622.   
  623.   if (rendermethod == WIREFRAME) 
  624.   { 
  625.    for (i = 0; i < totalobjects; i++)
  626.       wset_object_color (i, 63);
  627.    render_all = 1;
  628.   } 
  629.  
  630.  
  631.  if (motion_blur)
  632.   wcreate_shadesource_table (pal);
  633.  
  634.  
  635.  wsetscreen (virt);
  636.  
  637.  installkbd ();
  638.  
  639.  winittimer();
  640.  wstarttimer (movement_timer, TICKS(64));
  641.  
  642.  for (i = 0; i < totalobjects; i++)
  643.     map_points (i, vertices, scale);
  644.   
  645.   /* Main loop */
  646.   do
  647.    {
  648.      drawnum = 0;
  649.      
  650.      wset_light (camera_x, camera_y, camera_z);
  651.      wset_camera (camera_x, camera_y, camera_z);
  652.      wset_focus (focus_x, focus_y, focus_z);
  653.      wset_view ();
  654.  
  655.      for (i = 0; i < totalobjects; i++)
  656.        wworld_2_view (&objectlist[i], &drawnum, vertices);
  657.  
  658.      wsetscreen (virt);
  659.      
  660.      if (!motion_blur)
  661.       wcls (0);
  662.      else
  663.        shade_screen ();
  664.      
  665.      draw_polys (vertices, drawnum);
  666.  
  667.      wtextcolor (255);   
  668.      wgtprintf (0, 0, NULL, "Polys: %d", drawnum);
  669.  
  670.      if (kbdon[0x3B]) /* F1 Load */
  671.     load_ptext (totalpoly);
  672.  
  673.      if (kbdon[0x3D]) /* F3 Save */
  674.     save_ptext (totalpoly);
  675.  
  676.      if (kbdon[29]) /* CTRL */
  677.        {
  678.     rx = ry = rz = 0;
  679.  
  680.     if (kbdon[72]) // up
  681.       ry -= movectr;
  682.     if (kbdon[80]) // down
  683.       ry += movectr;
  684.     if (kbdon[0x4b]) // left
  685.       rx -= movectr;
  686.     if (kbdon[0x4d]) // right
  687.       rx += movectr;
  688.     if (kbdon[73]) // PGUP
  689.       rz -= movectr;
  690.     if (kbdon[81]) // PGDN
  691.       rz += movectr;
  692.  
  693.     if ((rx != 0) || (ry != 0) || (rz != 0))
  694.           {      
  695.             for (i = 0; i < totalobjects; i++)
  696.              rotate_object (&objectlist[i], vertices, rx, ry, rz, 0, 0, 0);
  697.           }
  698.        }
  699.      else
  700.        {
  701.     if (kbdon[72]) /* up */
  702.         camera_y -= movectr;
  703.     if (kbdon[80]) /* down */
  704.         camera_y += movectr;
  705.     if (kbdon[0x4b]) /* left */
  706.        camera_x -= movectr;
  707.     if (kbdon[0x4d]) /* right */
  708.        camera_x += movectr;
  709.     if (kbdon[73]) /* PGUP */
  710.        camera_z -= movectr;
  711.     if (kbdon[81]) /* PGDN */
  712.        camera_z += movectr;
  713.        }
  714.  
  715.     wtextcolor (255);
  716.     wtexttransparent (TEXTFGBG);
  717.     if (kbdon[78]) /* PLUS key */
  718.      {
  719.     movectr = movectr + 0.3;
  720.     wgtprintf (0, 0, NULL, "New movement amount for camera: %7.1f", movectr);
  721.      }
  722.  
  723.     if (kbdon[74]) /* MINUS key */
  724.      {
  725.     movectr = movectr - 0.3;
  726.     wgtprintf (0, 0, NULL, "New movement amount for camera: %7.1f", movectr);
  727.      }
  728.  
  729.     if (kbdon[23]) /* I key */
  730.      {
  731.     scale += 0.1;
  732.         for (i = 0; i < totalobjects; i++)
  733.            map_points (i, vertices, scale);
  734.      }
  735.  
  736.     if (kbdon[24]) /* O key */
  737.      {
  738.     scale -= 0.1;
  739.         for (i = 0; i < totalobjects; i++)
  740.            map_points (i, vertices, scale);
  741.      }
  742.  
  743.     
  744.  
  745.     if (movectr < 0.3)
  746.       movectr = 0.3;
  747.  
  748.     wnormscreen ();
  749.     if (WGT_SYS.bankswitch != NULL)
  750.       wvesa_putblock (0, 0, virt, NORMAL);
  751.     else memcpy (abuf, virt+4, 64000);
  752.     //wputblock (0, 0, virt, NORMAL);
  753.   
  754.   } while (!kbdon[1]);  /* Until ESC is hit */
  755.  
  756.   wstoptimer ();
  757.   wdonetimer ();
  758.   
  759.   wsetmode (oldmode);
  760.  
  761.   uninstallkbd ();
  762.  
  763.   wdeinit_triangle_renderer ();
  764.  
  765.   wfreeblock (virt);
  766.  
  767.   if ((rendermethod == FLAT_SHADED_TEXTURE) ||
  768.       (rendermethod == GOURAUD_SHADED_TEXTURE) ||
  769.       (rendermethod == PHONG_TEXTURE))
  770.     free (shadetable);
  771.   if ((rendermethod >= TEXTURE) && (rendermethod <= TRANSLUCENT_TEXTURE))
  772.     wfreeblock (textures[0]);
  773.   if ((rendermethod == TRANSLUCENT_TEXTURE) || 
  774.       (rendermethod == TRANSLUCENT_GOURAUD) ||
  775.       (rendermethod == TRANSLUCENT_PHONG))
  776.     free (translucent_table);
  777. }
  778.  
  779.  
  780.  
  781.